package com.phantasy.loaders.gameLoader
{
	import com.phantasy.caches.CacheURLLoader;
	import com.phantasy.loaders.Decoder;
	import com.phantasy.loaders.ResourcePool;
	import com.phantasy.scene.sceneUnit.baseUnit.things.resource.SourceManager;
	
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLRequest;
	import flash.utils.ByteArray;
	import flash.utils.Dictionary;

	
	public class GameLoader extends EventDispatcher 
	{
		
		private static var instance:GameLoader;
		
		public var MAX_LOADER_COUNT:int = 6;
		private var urlLoaders:Array;
		private var sources:Array;
		private var loadingLoader:Dictionary;
		private var registerDic:Dictionary;
		public var decoder:Decoder;
		
		public function GameLoader()
		{
			var _local1:CacheURLLoader;
			this.decoder = new Decoder();
			super();
			this.urlLoaders = [];
			this.sources = [];
			this.loadingLoader = new Dictionary();
			this.registerDic = new Dictionary();
			this.decoder.contentLoaderInfo.addEventListener(Event.COMPLETE, this.decoderComplete);
			this.decoder.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, this.decoderError);
			while (this.urlLoaders.length < this.MAX_LOADER_COUNT)
			{
				_local1 = new CacheURLLoader();
				_local1.dataFormat = URLLoaderDataFormat.BINARY;
				_local1.addEventListener(Event.COMPLETE, this.completeHandler);
				_local1.addEventListener(ProgressEvent.PROGRESS, this.onProgressHandler);
				_local1.addEventListener(IOErrorEvent.IO_ERROR, this.ioErrorHandler);
				this.urlLoaders.push(_local1);
			};
		}
		
		public static function getInstance():GameLoader
		{
			if (instance == null)
			{
				instance = new (GameLoader)();
			};
			return (instance);
		}
		
		public function add(url:String, priority:int=1, _arg3:Boolean=true, _arg4:Object=null, _arg5:Function=null, _arg6:Function=null, _arg7:Function=null):void
		{
			var _local9:Array;
			var _local8:ResourceItem = new ResourceItem();
			_local8.url = url;
			_local8.priority = priority;
			_local8.isNeedSave = _arg3;
			_local8.data = _arg4;
			_local8.handler = _arg5;
			_local8.processHandler = _arg6;
			_local8.errorHandler = _arg7;
			_local8.loading = false;
			_local8.content = null;
			if (!this.registerDic[url])
			{
				this.registerDic[_local8.url] = [_local8];
				this.addItem(_local8);
				this.load();
			}
			else
			{
				_local9 = this.registerDic[_local8.url];
				_local9.push(_local8);
			};
		}
		
		private function addItem(_arg1:ResourceItem):void
		{
			this.sources.push(_arg1);
			this.sources.sortOn("priority", Array.NUMERIC);
		}
		
		private function getLoader():CacheURLLoader
		{
			if (((this.urlLoaders) && ((this.urlLoaders.length > 0))))
			{
				return (this.urlLoaders.pop());
			};
			return (null);
		}
		
		private function load():void
		{
			var _local1:CacheURLLoader;
			var _local2:ResourceItem;
			if (this.sources.length > 0)
			{
				_local1 = this.getLoader();
				if (_local1)
				{
					_local2 = this.sources.shift();
					this.loadingLoader[_local1] = _local2;
					_local1.load(new URLRequest(_local2.url));
					this.load();
				};
			};
		}
		
		private function onProgressHandler(_arg1:ProgressEvent):void
		{
			var _local4:Number;
			var _local2:CacheURLLoader = (_arg1.currentTarget as CacheURLLoader);
			var _local3:ResourceItem = this.loadingLoader[_local2];
			if (_local3.processHandler != null)
			{
				_local4 = (_arg1.bytesLoaded / _arg1.bytesTotal);
				_local3.processHandler.call(null, _local4);
			};
		}
		
		private function completeHandler(_arg1:Event):void
		{
			var _local2:CacheURLLoader = (_arg1.currentTarget as CacheURLLoader);
			var _local3:ResourceItem = this.loadingLoader[_local2];
			delete this.loadingLoader[_local2];
			if (_local3)
			{
				if ((((_local3.type == ResourceItem.SWF)) || ((_local3.type == ResourceItem.IMAGE))))
				{
					_local3.content = (_local2.datas as ByteArray);
					this.decoder.add(_local3);
				}
				else
				{
					if (_local3.type == ResourceItem.FILE)
					{
						if (_local3.isNeedSave == true)
						{
							ResourcePool.add(_local3.url, _local2.datas);
						}
						_local3.handler.call(null, _local2.datas);
						delete this.registerDic[_local3.url];
					}
				}
			}
			this.urlLoaders.push(_local2);
			this.load();
		}
		
		private function decoderComplete(e:Event):void
		{
			var decoder:Decoder;
			var item:ResourceItem;
			var list:Array;
			var length:int;
			var i:int;
			var childItem:ResourceItem;
			try
			{
				decoder = (e.target.loader as Decoder);
				item = decoder.info;
				list = this.registerDic[item.url];
				length = list.length;
				i = 0;
				while (i < length)
				{
					childItem = list[i];
					if (childItem.isNeedSave == true)
					{
						ResourcePool.add(childItem.url, decoder.contentLoaderInfo.applicationDomain);
						childItem.handler.call(null, childItem.data);
					}
					else
					{
						childItem.handler.call(null, decoder, childItem.data);
					};
					i = (i + 1);
				};
				delete this.registerDic[item.url];
			}
			catch(e:Error)
			{
			};
			decoder.dispose();
		}
		
		private function ioErrorHandler(_arg1:IOErrorEvent):void
		{
			var _local5:ResourceItem;
			var _local2:CacheURLLoader = (_arg1.currentTarget as CacheURLLoader);
			var _local3:ResourceItem = this.loadingLoader[_local2];
			delete this.loadingLoader[_local2];
			var _local4:Array = this.registerDic[_local3.url];
			if (((_local4) && ((_local4.length > 0))))
			{
				while (_local4.length > 0)
				{
					_local5 = _local4.pop();
					if (_local5.errorHandler != null)
					{
						_local5.errorHandler.call(null, null);
					};
				};
			};
			this.urlLoaders.push(_local2);
		}
		
		private function decoderError(_arg1:IOErrorEvent):void
		{
			this.decoder.dispose();
		}
		
		public function clearAll():void
		{
			var loader:Object;
			for (loader in this.loadingLoader)
			{
				this.unLoadLoader((loader as CacheURLLoader));
			};
			this.loadingLoader = new Dictionary();
			this.registerDic = new Dictionary();
			this.sources.length = 0;
			try
			{
				this.decoder.close();
			}
			catch(e:Error)
			{
			};
			this.decoder.isDecoding = false;
			this.decoder.decodelist.length = 0;
			SourceManager.getInstance().deleteLoadingDic();
		}
		
		private function unLoadLoader(_arg1:CacheURLLoader):void
		{
			_arg1.close();
			this.urlLoaders.push(_arg1);
		}
		
		
	}
}
